<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/3/19
 * Time: 14:11
 */
namespace App\Services;
use App\Models\Admin\Activity;
use App\Enum\ActivityEnum;
use Illuminate\Support\Facades\Redis;

class ActivityService
{
    private static $_msg = ['code' => 0, 'msg' => ''];

    /**
     * @desc 创建活动配置
     * @param $params
     * @return array
     */
    public static function add_activity($params)
    {
        if(!self::_check_invite_data($params)) {
            return self::$_msg;
        }

        $current_time = time();
        $activity_data = self::_handle_data($params);
        $activity_data['created_at'] = $activity_data['updated_at'] = time2date($current_time);
        $activity_data['last_settlement_time'] = $current_time;
        $activity_data['next_settlement_time'] = $activity_data['settlement_type'] == ActivityEnum::ACTIVITY_SETTLEMENT_TYPE_WEEK ? strtotime('+1 week last monday') : strtotime(date('Y-m-1',strtotime('next month')));

        $activity_id = Activity::insertGetId($activity_data);
        if(!$activity_id) {
            self::_set_msg(10000, '创建活动设置失败');
        } else {
            self::$_msg['activity_id'] = $activity_id;
        }

        return self::$_msg;
    }

    /**
     * @desc 修改活动配置
     * @param $params
     * @return array
     */
    public static function modify_activity($params)
    {
        if(empty($params['id'])) {
            self::_set_msg(10000, '未选择活动配置');
            return self::$_msg;
        }
        $is_record = Activity::where(['id'=> $params['id']])->first();
        if(!$is_record) {
            self::_set_msg(10000, '活动配置数据异常');
            return self::$_msg;
        }
        if($is_record->activity_type == ActivityEnum::ACTIVITY_TYPE_INVITE) {
            // 检测邀请活动数据
            if(!self::_check_invite_data($params)) {
                return self::$_msg;
            }
        } else {
            // 检测集赞活动数据
            if(!self::_check_like_data($params)) {
                return self::$_msg;
            }
        }


        $activity_data = self::_handle_data($params);
        $activity_data['updated_at'] = time2date();

        // 邀请活动
        if($is_record->activity_type == ActivityEnum::ACTIVITY_TYPE_INVITE) {
            // 变更结算周期，处理上一次或下一次的生成结算时间
            if($is_record->settlement_type != $params['settlement_type']) {
                $current_time = time();
                $activity_data['last_settlement_time'] = $current_time;
                $activity_data['next_settlement_time'] = $params['settlement_type'] == ActivityEnum::ACTIVITY_SETTLEMENT_TYPE_WEEK ? (strtotime('+1 week last monday') - 1) : (strtotime(date('Y-m-1',strtotime('next month'))) - 1);
                $is_record->next_settlement_time = $current_time - 1;
            }

            if(!Activity::where(['id' => $params['id']])->update($activity_data)) {
                return self::_set_msg(10000, '修改活动设置失败');
            }

            // 变更结算周期生成待结算的列表
            if($is_record->settlement_type != $params['settlement_type']) {
                Redis::rpush("Invite_Settlement_data", json_encode($is_record->toArray()));    // 写入邀请结算
            }
        } else {
            if(!Activity::where(['id' => $params['id']])->update($activity_data)) {
                return self::_set_msg(10000, '修改活动设置失败');
            }
        }


        return self::$_msg;
    }

    /**
     * @desc 检测活动数据(邀请活动)
     * @param $params
     * @return bool
     */
    private static function _check_invite_data($params)
    {
        if(empty($params['content'])) {
            self::_set_msg(10000, '活动内容不能为空');
            return false;
        }
        if(empty($params['settlement_type'])) {
            self::_set_msg(10000, '请输入奖励结算周期');
            return false;
        }
        if(empty($params['activity_strategy'])) {
            self::_set_msg(10000, '请输入奖金设置');
            return false;
        }
        // 检测内容
        if(mb_strlen($params['content']) > 500) {
            self::_set_msg(10000, '活动内容不能超过500个字符');
            return false;
        }

        // 活动开始时间
        if(strtotime($params['start_time']) == false) {
            self::_set_msg(10000, '活动开始时间有误');
            return false;
        }

        // 活动结束时间
        if(strtotime($params['end_time']) == false) {
            self::_set_msg(10000, '活动结束时间有误');
            return false;
        }

        // 开始时间不能大于结束时间
        if(strtotime($params['start_time']) > strtotime($params['end_time'])) {
            self::_set_msg(10000, '活动开始时间不能大于结束时间');
            return false;
        }

        // 检测活动状态
        if(!in_array($params['status'], [ActivityEnum::ACTIVITY_STATUS_INVALIDATE, ActivityEnum::ACTIVITY_STATUS_VALID])) {
            self::_set_msg(10000, '活动状态异常');
            return false;
        }

        // 检测结算类型(1:周;2:月)
        if(!in_array($params['settlement_type'], [ActivityEnum::ACTIVITY_SETTLEMENT_TYPE_WEEK, ActivityEnum::ACTIVITY_SETTLEMENT_TYPE_MONTH])) {
            self::_set_msg(10000, '奖励结算周期异常');
            return false;
        }

        // 活动策略
        if(!self::_check_strategy($params)) {
            return false;
        }

        return true;
    }

    /**
     * @desc 检测活动数据(邀请活动)
     * @param $params
     * @return bool
     */
    private static function _check_like_data($params)
    {
        // 活动开始时间
        if(strtotime($params['start_time']) == false) {
            self::_set_msg(10000, '活动开始时间有误');
            return false;
        }

        // 活动结束时间
        if(strtotime($params['end_time']) == false) {
            self::_set_msg(10000, '活动结束时间有误');
            return false;
        }

        // 开始时间不能大于结束时间
        if(strtotime($params['start_time']) > strtotime($params['end_time'])) {
            self::_set_msg(10000, '活动开始时间不能大于结束时间');
            return false;
        }

        if(strtotime($params['last_show_time']) == false) {
            self::_set_msg(10000, '活动最后显示时间不能为空');
            return false;
        }

        if(strtotime($params['last_show_time']) < strtotime($params['end_time'])) {
            self::_set_msg(10000, '最后显示时间时间不能早于活动结束时间');
            return false;
        }

        // 检测活动状态
        if(!in_array($params['status'], [ActivityEnum::ACTIVITY_STATUS_INVALIDATE, ActivityEnum::ACTIVITY_STATUS_VALID])) {
            self::_set_msg(10000, '活动状态异常');
            return false;
        }

        if(empty($params['activity_photos'])) {
            self::_set_msg(10000, '活动图片不能为空');
            return false;
        }

        return true;
    }

    /**
     * @desc 检测奖励策略
     * @param $params
     * @return bool
     */
    private static function _check_strategy($params)
    {
        if(!is_array($params['activity_strategy'])) {
            self::_set_msg(10000, '奖励设置数据结构不正确');
            return false;
        }
        $activity_strategy = $params['activity_strategy'];
        $temp_strategy = [];
        foreach($activity_strategy as $strategy) {
            $temp_strategy[$strategy['reward_user']] = $strategy['reward_user'];
            if(!in_array($strategy['reward_user'], [ActivityEnum::ACTIVITY_REWARD_USER_GENERAL, ActivityEnum::ACTIVITY_REWARD_USER_MEMBER, ActivityEnum::ACTIVITY_REWARD_USER_SHAREHOLDER])) {
                self::_set_msg(10000, '奖励对象异常');
                return false;
            }

            if(!in_array($strategy['reward_units'], [ActivityEnum::ACTIVITY_REWARD_UNITS_TOTAL ,ActivityEnum::ACTIVITY_REWARD_UNITS_SINGLE])) {
                self::_set_msg(10000, '奖励金额单位异常');
                return false;
            }

            // 检测奖励金额(区间元及人数/元)
            if(empty($strategy['list'])) {
                self::_set_msg(10000, '推广人数区间及金额异常');
                return false;
            }

            // 检测策略
            $temp_number = 0;
            foreach($strategy['list'] as $section) {
                if(($temp_number != 0) && ($temp_number != $section['start_number'])) {
                    self::_set_msg(10000, '推广人数区间不连续');
                    return false;
                }
                if($section['start_number'] == 0 || $section['end_number'] == 0) {
                    self::_set_msg(10000, '推广人数不能不能设置为0');
                    return false;
                }
                if($section['start_number'] > $section['end_number']) {
                    self::_set_msg(10000, '推广人数起始人数不能大于结束人数');
                    return false;
                }

                // 检测元的金额
                if(!is_numeric($section['reward_amount'])) {
                    self::_set_msg(10000, '奖励金额数据不合法');
                    return false;
                }

                $temp_number = $section['end_number'] + 1;
            }
        }

        if(count($temp_strategy) < count($activity_strategy)) {
            self::_set_msg(10000, '奖励对象存在重复');
            return false;
        }

        return true;
    }

    /**
     * @desc 整合数据
     * @param $params
     * @return array
     */
    private static function _handle_data($params)
    {
        $activity_strategy = [];
        if(!empty($params['activity_strategy'])) {
            foreach($params['activity_strategy'] as $strategy) {
                $user_strategy = [
                    'reward_user' => (int)$strategy['reward_user'],
                    'reward_units' => (int)$strategy['reward_units'],
                ];
                foreach($strategy['list'] as $section) {
                    $user_strategy['list'][] = [
                        'start_number' => (int)$section['start_number'],
                        'end_number' => (int)$section['end_number'],
                        'reward_amount' => $section['reward_amount'],
                    ];
                }

                $activity_strategy[] = $user_strategy;
            }
        }

        $data = [
            'operator_id' => $params['operator_id'],
            'content' => $params['content'],
            'start_time' => strtotime($params['start_time']),
            'end_time' => strtotime($params['end_time']),
            'status' => (int)$params['status'],
            'activity_strategy' => json_encode($activity_strategy),
            'activity_photos' => $params['activity_photos'] ? clear_urlcan($params['activity_photos']) : '',
            'last_show_time' => $params['last_show_time'] ? strtotime($params['last_show_time']) : 0,
        ];
        if(!empty($params['settlement_type'])) {
            $data['settlement_type'] = (int)$params['settlement_type'];
        }

        return $data;
    }

    /**
     * @desc 设置提示信息
     * @param $code
     * @param $msg
     * @return array
     */
    private static function _set_msg($code, $msg)
    {
        return self::$_msg = ['code' => $code, 'msg' => $msg];
    }
}